package com.hhkj.api.student.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hhkj.admin.course.common.cont.CourseConst;
import com.hhkj.admin.course.domain.Course;
import com.hhkj.admin.course.domain.CourseBankType;
import com.hhkj.admin.course.domain.CoursePriceConf;
import com.hhkj.admin.course.model.res.CourseRes;
import com.hhkj.admin.course.service.base.CoursePriceConfService;
import com.hhkj.admin.course.service.extend.CourseBankTypeExtendService;
import com.hhkj.admin.course.service.extend.CoursePriceConfExtendService;
import com.hhkj.admin.student.common.cont.StudentConst;
import com.hhkj.admin.student.common.utils.StudentUtils;
import com.hhkj.admin.student.domain.Student;
import com.hhkj.admin.student.domain.StudentBatch;
import com.hhkj.admin.student.domain.StudentCourse;
import com.hhkj.admin.student.model.dopo.StudentCoursePo;
import com.hhkj.admin.student.model.dopo.StudentPo;
import com.hhkj.admin.student.service.base.StudentBatchService;
import com.hhkj.admin.student.service.base.StudentCourseService;
import com.hhkj.admin.student.service.base.StudentService;
import com.hhkj.admin.student.service.extend.StudentCourseExtendService;
import com.hhkj.admin.student.service.extend.StudentExtendService;
import com.hhkj.api.common.common.component.checker.CaptchaChecker;
import com.hhkj.api.common.common.cont.SaleCaptchaTypeEnum;
import com.hhkj.api.course.service.biz.ApiSaleCourseBizService;
import com.hhkj.api.student.model.req.ApiSaleStudentCourseListReq;
import com.hhkj.api.student.model.req.ApiSaleStudentRegisterReq;
import com.hhkj.api.student.model.res.ApiSaleStudentCourseListRes;
import com.hhkj.api.student.service.biz.ApiSaleStudentBizService;
import com.ruoyi.common.cont.SysConst;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ApiSaleStudentBizServiceImpl
 *
 * @author HHKJ-SERVER-ZJ
 * @since 2023/12/26 15:32
 */
@Service
public class ApiSaleStudentBizServiceImpl implements ApiSaleStudentBizService {

    @Autowired
    private StudentService studentService;
    @Autowired
    private CaptchaChecker captchaChecker;
    @Autowired
    private StudentExtendService studentExtendService;
    @Autowired
    private ApiSaleCourseBizService saleCourseBizService;
    @Autowired
    private StudentCourseExtendService studentCourseExtendService;
    @Autowired
    private StudentCourseService studentCourseService;
    @Autowired
    private CoursePriceConfExtendService priceConfExtendService;
    @Autowired
    private CourseBankTypeExtendService courseBankTypeExtendService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private StudentBatchService studentBatchService;
    @Autowired
    private CoursePriceConfService coursePriceConfService;


    @Override
    public List<ApiSaleStudentCourseListRes> listCourse(ApiSaleStudentCourseListReq studentReq) {
        List<StudentPo> studentList = studentService.selectStudentCourseByDo(studentReq);
        List<CoursePriceConf> priceConfList = coursePriceConfService.list();
        List<Long> courseIdList = priceConfList.stream()
                .sorted(Comparator.comparing(CoursePriceConf::getPrice).reversed())
                .map(CoursePriceConf::getCourseId)
                .collect(Collectors.toList());
        Map<Long, List<ApiSaleStudentCourseListRes>> resListByCourseParentIdMap = studentList.stream()
                .map(studentPo -> BeanUtil.toBean(studentPo, ApiSaleStudentCourseListRes.class))
                .collect(Collectors.groupingBy(StudentPo::getCourseParentId));
        List<ApiSaleStudentCourseListRes> resList = new ArrayList<>();
        // 根据数据
        Set<Long> courseIdSet = new HashSet<>();
        for (Long courseId : courseIdList) {
            if (courseIdSet.contains(courseId)) {
                continue;
            }
            courseIdSet.add(courseId);
            if (resListByCourseParentIdMap.containsKey(courseId)) {
                resList.addAll(resListByCourseParentIdMap.get(courseId));
            }
        }
        return resList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(ApiSaleStudentRegisterReq req) {
        this.checkRegisterInfoFormat(req);
        // 1、验证码校验
        captchaChecker.check(SaleCaptchaTypeEnum.REGISTER_STUDENT.getCode(), req.getPhone(), req.getCaptcha());
        // 2、确认系统中是否有这个学员student信息
        Student studentPo = this.getStudentOrSaveIfNotExist(req);
        // 3、检验课程是否免费
        Map<Long, Course> courseByIdMap = saleCourseBizService.listFreePrice()
                .stream()
                .collect(Collectors.toMap(Course::getId, Function.identity()));
        if (!courseByIdMap.containsKey(req.getCourseId())) {
            throw new GlobalException("所选课程无效，请刷新后重新再试");
        }
        // 4、查看当前学生是否已经有对应科目的报考信息
        StudentCoursePo studentCoursePo
                = studentCourseExtendService.getPo(
                req.getIdCard(),
                req.getCourseId(),
                StudentConst.AuditCode.STATUS_PASS.getCode());
        if (ObjectUtil.isNotNull(studentCoursePo)) {
            throw new GlobalException("账号已存在");
        }
        // 5、没有的话创建学员课程信息
        Course coursePo = courseByIdMap.get(req.getCourseId());
        return this.createStudentCourse(coursePo, studentPo);
    }

    @Override
    public List<CourseRes> multiListCourse(ApiSaleStudentCourseListReq studentReq) {
        List<StudentPo> studentList = studentService.selectStudentCourseByDo(studentReq);
        List<Long> courseIdList = studentList.stream().map(StudentPo::getCourseId).collect(Collectors.toList());
        if (CollUtil.isEmpty(courseIdList)) {
            return Lists.newArrayList();
        }
        // 所有的课程信息列表
        List<Course> courseAllList = saleCourseBizService.listCourseTreeAllList(null);
        // 过滤掉隐藏的课程列表
        courseAllList = courseAllList.stream().filter(e -> SysConst.Flag.NO.getFlag().equals(e.getNeedHiddenFlag())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(courseAllList)) {
            return Lists.newArrayList();
        }
        List<CourseRes> courseResAllList = BeanUtil.copyToList(courseAllList, CourseRes.class);
        // 学员报考课程列表
        List<Course> studentCourseList = courseAllList.stream().filter(course -> courseIdList.contains(course.getId())).collect(Collectors.toList());
        if (CollUtil.isEmpty(studentCourseList)) {
            return Lists.newArrayList();
        }
        // 所有课程列表Map
        Map<Long, CourseRes> courseAllMap = courseResAllList.stream().collect(Collectors.toMap(Course::getId, Function.identity()));
        Map<Long, List<Course>> studentCourseParentResMap = studentCourseList.stream().collect(Collectors.groupingBy(Course::getParentId));

        // 二级目录
        Set<Long> secondLevelCourseIdList = studentCourseParentResMap.keySet();
        List<Course> secondeCourseList = courseAllList.stream().filter(course -> secondLevelCourseIdList.contains(course.getId())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(secondeCourseList)) {
            return Lists.newArrayList();
        }
        for (Course course : secondeCourseList) {
            if (studentCourseParentResMap.containsKey(course.getId())) {
                course.setChildren(studentCourseParentResMap.get(course.getId()));
            }
        }

        List<CourseRes> finalCourseResList = Lists.newArrayList();
        Map<Long, List<Course>> topParentCourse = secondeCourseList.stream().collect(Collectors.groupingBy(Course::getParentId));
        topParentCourse.forEach((id, courseResList) -> {
            CourseRes courseRes = courseAllMap.get(id);
            if (ObjectUtil.isNotNull(courseRes)) {
                courseRes.setChildren(courseResList);
                finalCourseResList.add(courseRes);
            }
        });

        return finalCourseResList;
    }



    /**
     * 创建学员信息
     *
     * @param coursePo  课程信息
     * @param studentPo 学员信息
     * @return true/false
     */
    private boolean createStudentCourse(Course coursePo, Student studentPo) {
        Date currentDate = new Date();
        SysUser defaultUser = userService.getDefaultUser();
        // 5、创建批次
        StudentBatch studentBatchDo = StudentBatch.builder()
                .insId(defaultUser.getUserId())
                .payFlag(SysConst.Flag.IS.getFlag().longValue())
                .payDate(currentDate)
                .payPrice(BigDecimal.ZERO)
                .status(StudentConst.AuditCode.STATUS_PASS.getCode())
                .build();
        studentBatchDo.setCreateBy(defaultUser.getUserId());
        studentBatchService.save(studentBatchDo);
        // 5.1、获取课程价格信息
        CoursePriceConf coursePricePo = priceConfExtendService.getByCourseId(coursePo.getParentId());
        CourseBankType defaultTypeByCoursePo = courseBankTypeExtendService.getDefaultTypeByCourseId(coursePo.getParentId());
        StudentCourse studentCourseDo = new StudentCourse();
        studentCourseDo.setStudentId(studentPo.getId());
        studentCourseDo.setCourseId(coursePo.getId());
        studentCourseDo.setBatchId(studentBatchDo.getId());
        studentCourseDo.setInsId(defaultUser.getUserId());
        studentCourseDo.setStatus(StudentConst.AuditCode.STATUS_PASS.getCode());
        // 5.2、获取默认题库类型
        studentCourseDo.setCourseBankTypeId(defaultTypeByCoursePo.getId());
        studentCourseDo.setStartDate(currentDate);
        studentCourseDo.setUnitPayPrice(BigDecimal.ZERO);
        Integer dayAmount = coursePricePo.getDayAmount();
        // 截止时间需要延后一天保证天数
        DateTime lineDate = DateUtil.offsetDay(currentDate, ++dayAmount);
        studentCourseDo.setLineDate(lineDate);
        studentCourseDo.setCreateBy(defaultUser.getUserId());
        return studentCourseService.save(studentCourseDo);
    }

    /**
     * 获取学生信息，如果不存在创建学员信息
     *
     * @param req 请求信息
     * @return 学员信息
     */
    private Student getStudentOrSaveIfNotExist(ApiSaleStudentRegisterReq req) {
        // 2、确认系统中是否有这个学员student信息
        Student studentPo = studentExtendService.getByIdCard(req.getIdCard());
        SysUser defaultUser = userService.getDefaultUser();
        if (ObjectUtil.isNull(studentPo)) {
            //  2.1、创建学员信息
            Student studentDo = new Student();
            studentDo.setName(req.getName());
            studentDo.setIdCard(req.getIdCard());
            studentDo.setPhone(req.getPhone());
            StudentUtils.encryptPassword(studentDo);
            studentDo.setCreateBy(defaultUser.getUserId());
            studentService.save(studentDo);
            studentPo = studentDo;
        } else if (!req.getPhone().equals(studentPo.getPhone())) {
            // 2.2、修改学员 信息
            // studentPo.setName(req.getName());
            studentPo.setPhone(req.getPhone());
            studentService.updateById(studentPo);
        }
        return studentPo;
    }

    /**
     * 注册信息校验
     *
     * @param req 请求信息
     */
    private void checkRegisterInfoFormat(ApiSaleStudentRegisterReq req) {
//        if (!IdcardUtil.isValidCard(req.getIdCard())) {
//            throw new GlobalException("身份证号码格式错误！");
//        }
        if (!PhoneUtil.isMobile(req.getPhone())) {
            throw new GlobalException("手机号码格式错误！");
        }
    }
}
